home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
350_01
/
pcx_file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-29
|
50KB
|
1,378 lines
/*
*************************************************************************
*
* PCX_FILE.C - PCX_LIB Library Image File Functions
*
* Version: 1.00C
*
* History: 91/02/14 - Created
* 91/04/01 - Release 1.00A
* 91/04/03 - Fixed "segread" call.
* 91/04/07 - Release 1.00B
* 91/11/18 - Fixed "pcx_init_palette" and "pcx_write_extpal"
* for large memory model.
* - Made default EGA palette register values
* array "_far".
* 91/12/01 - Release 1.00C
*
* Compiler: Microsoft C V6.0
*
* Author: Ian Ashdown, P.Eng.
* byHeart Software
* 620 Ballantree Road
* West Vancouver, B.C.
* Canada V7S 1W3
* Tel. (604) 922-6148
* Fax. (604) 987-7621
*
* Copyright: Public Domain
*
*************************************************************************
*/
/*
*************************************************************************
*
* PORTABILITY NOTES
*
* 1. While this program is written in ANSI C, it uses a number of
* function calls that are specific to the Microsoft C V6.0 library.
* These are documented as follows for the purposes of porting this
* program to other compilers and/or processors:
*
* _ffree - "free" for small model / far data
* _fmalloc - "malloc" for small model / far data
* _fmemcpy - "memcpy" for small model / far data
* int86 - execute 80x86 interrupt routine
* int86x - execute 80x86 interrupt routine (far data)
* outpw - output word to 80x86 I/O port
*
* 2. When porting this program to other processors, remember that words
* are stored by 80x86-based machines in the big-endian format. That
* is, the eight least significant bits (lower byte) are stored
* first, followed by the eight most significant bits (upper byte).
* If PCX-format files are transferred to little-endian machines
* (such as those based on 680x0 and Z8000 processors), the order of
* bytes within each word will have to be reversed before they can
* be interpreted. (This applies to the file header only, since the
* encoded image data and optional 256-color palette are stored as
* bytes.)
*
* 3. MS-DOS does not recognize the 720 x 348 graphics mode of the
* Hercules monochrome display adapter. Therefore, the constant
* PCX_HERC should never be passed as a video mode parameter to any
* BIOS service routine.
*
* The Microsoft C compiler includes a "video mode" parameter
* definition (_HERCMONO) that is defined as 0x08. This is a
* reserved MS-DOS video mode that is apparently used internally by
* the ROM BIOS. It can, however, be passed to the Microsoft C
* library function "_setvideomode" to force the Hercules display
* adapter into graphics mode.
*
* Most other MS-DOS C compilers offer similar library functions to
* force the Hercules monochrome display adapter into its 720 x 348
* graphics mode.
*
*************************************************************************
*/
/* INCLUDE FILES */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <malloc.h>
#include <dos.h>
#include <graph.h>
#include "pcx_int.h"
/* FORWARD REFERENCES */
static BOOL pcx_encode(int, int, FILE *);
static BOOL pcx_init_palette(PCX_PAL *, int);
static BOOL pcx_write_extpal(FILE *);
static BOOL pcx_write_line(unsigned char *, int, FILE *);
static BOOL pcx_write_init(PCX_WORKBLK *, int, int, int, int);
static void pcx_get_cga(PCX_WORKBLK *, unsigned char _far *, int);
static void pcx_get_ega(PCX_WORKBLK *, unsigned char _far *, int);
static void pcx_get_herc(PCX_WORKBLK *, unsigned char _far *, int);
static void pcx_get_vga(PCX_WORKBLK *, unsigned char _far *, int);
/* GLOBALS */
/* Default EGA palette register values */
static BYTE _far pcx_EGA_DefPal_1[16] = /* Modes 0x0d and 0x0e */
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17
};
static BYTE _far pcx_EGA_DefPal_2[16] = /* Mode 0x0f */
{
0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
0x00, 0x18, 0x00, 0x00
};
static BYTE _far pcx_EGA_DefPal_3[16] = /* Mode 0x10 */
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f
};
/* PUBLIC FUNCTIONS */
/*
*************************************************************************
*
* PCX_WRITE - Write PCX File
*
* Purpose: To write a PCX-format image file from an image stored in
* a video buffer. The image is assumed to start in the
* upper left corner of the screen.
*
* Setup: BOOL pcx_write
* (
* char *fname,
* int vmode,
* int page,
* int width,
* int height,
* )
*
* Where: fname is a PCX image file name.
* vmode is the MS-DOS video mode. Valid values are:
*
* PCX_HERC - 720 x 348 Hercules monochrome
* 0x04 - 320 x 200 4-color CGA
* 0x05 - 320 x 200 4-color CGA (color burst off)
* 0x06 - 640 x 200 2-color CGA
* 0x0d - 320 x 200 16-color EGA/VGA
* 0x0e - 640 x 200 16-color EGA/VGA
* 0x0f - 640 x 350 2-color EGA/VGA
* 0x10 - 640 x 350 16-color EGA/VGA
* 0x11 - 640 x 480 2-color VGA
* 0x12 - 640 x 480 16-color VGA
* 0x13 - 320 x 200 256-color VGA
*
* page is the video display page number. Valid values are:
*
* Mode PCX_HERC - 0 or 1
* Mode 0x0d - 0 to 7
* Mode 0x0e - 0 to 3
* Mode 0x0f - 0 or 1
* Mode 0x10 - 0 or 1
* All Other - 0
*
* width is the image width in pixels.
* height is the image height in pixels.
*
* Return: TRUE if successful; otherwise FALSE.
*
*************************************************************************
*/
BOOL pcx_write
(
char *fname,
int vmode,
int page,
int width,
int height
)
{
int bpline; /* Number of bytes per scan line */
int line_num; /* Scan line number */
unsigned char *linep; /* Image scan line buffer pointer */
BOOL status = TRUE; /* Return status */
PCX_WORKBLK *wbp; /* PCX image file workblock pointer */
/* Open a PCX image file workblock */
if ((wbp = pcx_open(fname, TRUE)) == (PCX_WORKBLK *) NULL)
return (FALSE);
/* Initialize the workblock for writing */
if (pcx_write_init(wbp, vmode, page, width, height) == FALSE)
status = FALSE;
/* Calculate number of bytes per line (for all color planes) */
bpline = wbp->header.bppscan * wbp->header.nplanes;
/* Allocate a scan line buffer */
if (status == TRUE)
if ((linep = (unsigned char *) malloc(bpline)) == (unsigned char *)
NULL)
status = FALSE;
/* Write the file header to the file */
if (sta